<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>28.灵活的动画处理类29.容器管理类Slide定义 30.批量执行动画 31.动画队列的控制</title>
  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: content-box;
    }

    body {
      padding: 30px;
    }

    .slide {
      width: 300px;
      display: flex;
      flex-direction: column;
      /* box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3); */
    }

    .slide dt {
      height: 30px;
      background: #34495e;
      color: white;
      display: flex;
      align-items: center;
      padding-left: 10px;
      cursor: pointer;
    }

    .slide dt:first-of-type {
      border-top-left-radius: 10px;
      border-top-right-radius: 10px;
    }

    .slide dd {
      height: 100px;
      background: #f1c40f;
      overflow: hidden;
    }

    .slide dd div {
      padding: 10px;
    }

    .slide dd:last-of-type {
      border-bottom-left-radius: 10px;
      border-bottom-right-radius: 10px;
    }
  </style>
</head>


<body>
  <div class="slide s1">
    <dt>后盾人</dt>
    <dd>
      <div>houdunren.com</div>
    </dd>
    <dt>后盾人</dt>
    <dd>
      <div>hdcms.com</div>
    </dd>
    <dt>后盾人</dt>
    <dd>
      <div>hdcms.com</div>
    </dd>
  </div>
</body>

<script>
  class Animation {
    constructor(el) {
      this.el = el;
      this.timeout = 5;
      this.isShow = true;
      this.defaultHeight = this.height;
    }
    hide (callback) {
      this.isShow = false;
      let id = setInterval(() => {
        if (this.height <= 0) {
          clearInterval(id);
          callback && callback();
          return;
        }
        this.height = this.height - 1;
      }, this.timeout);
    }
    show (callback) {
      this.isShow = false;
      let id = setInterval(() => {
        if (this.height >= this.defaultHeight) {
          clearInterval(id);
          // 如果callback不为空则回调
          callback && callback();
          return;
        }
        this.height = this.height + 1;
      }, this.timeout);
    }
    get height () {
      // 这里获取的高度有像素单位，要去掉px
      // 加法运算时，获取的字符串类型高度会导致+1的运输变成 字符串末尾拼接字符 1，因此 x1 将数据类型转为数字类型
      return window.getComputedStyle(this.el).height.slice(0, -2) * 1;
    }
    set height (height) {
      this.el.style.height = height + "px";
    }
  }
  class Slide {
    constructor(el) {
      this.el = document.querySelector(el);
      this.links = this.el.querySelectorAll("dt");
      this.panels = [...this.el.querySelectorAll("dd")].map(
        item => new Panel(item)
      );
      this.bind();
    }
    // 绑定事件
    bind () {
      this.links.forEach((item, i) => {
        item.addEventListener("click", () => {
          this.action(i);
        });
      });
    }
    action (i) {
      Panel.hideAll(Panel.filter(this.panels, i), () => {
        this.panels[i].show();
      });
    }
  }
  class Panel extends Animation {
    static num = 0;
    static hideAll (items, callback) {
      if (Panel.num > 0) return;
      items.forEach(item => {
        Panel.num++;
        item.hide(() => {
          Panel.num--;
        });
      });
      callback && callback();
    }
    static filter (items, i) {
      return items.filter((item, index) => index != i);
    }
  }
  let hd = new Slide(".s1");
</script>

</html>